package cn.ante.user.service.impl;

import cn.ante.basic.exception.BusinessException;
import cn.ante.basic.utils.CheckCodeUtil;
import cn.ante.basic.utils.MD5Utils;
import cn.ante.basic.utils.StrUtils;
import cn.ante.basic.vo.RegisterVo;
import cn.ante.basic.constant.BaseContants;
import cn.ante.user.domain.Logininfo;
import cn.ante.user.domain.User;
import cn.ante.user.mapper.LogininfoMapper;
import cn.ante.user.mapper.UserMapper;
import cn.ante.user.service.IUserService;
import cn.ante.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.validation.constraints.Email;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Nai
 * @since 2022-07-06
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private UserMapper userMapper;

//    @Autowired
//    private IUserService userService;

    public User register2User(RegisterVo registerVo){
        // 获取对象
        User user = new User();
        String password = registerVo.getPassword();
        if (registerVo.getRegisterType().equals("phone")){
            // 获取参数
            String phone = registerVo.getPhone();
            // 设置属性
            user.setUsername(phone);
            user.setPhone(phone);
        }else if(registerVo.getRegisterType().equals("email")) {
            // 获取参数
            String email = registerVo.getEmail();
            // 设置属性
            user.setUsername(email);
            user.setEmail(email);
        }
        // 获取盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 获取MD5进行加盐加密
        String md5Password = MD5Utils.encrypByMd5(salt + password);
        user.setSalt(salt);
        user.setPassword(md5Password);
        return user;
    }


    public Logininfo user2Logininfo(User user){
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
       logininfo.setType(1);
        return logininfo;
    }

    /**
    * @Description: 用户手机注册账户
    * @Author: Nai
    * @Version: 1.0
    * @Date:  2022/7/10 19:56
    */
    @Override
    public void register(RegisterVo registerVo) {
        String registerType = registerVo.getRegisterType();
        // 注册业务逻辑判断
        if (registerType.equals("phone")){
            String phone = registerVo.getPhone();
            // 正则表达式校验手机号格式是否正确
            if (!Pattern.matches(BaseContants.VerifyShopSettlement.REGEX_MOBILE,phone)) {
                throw new BusinessException("请输入正确的手机号,请重新输入");
            }
            // 调用注册业务方法
            registerMethod(registerVo);
        }else if(registerType.equals("email")) {
            String email = registerVo.getEmail();
            // 正则表达式校验手机号格式是否正确
            if(!Pattern.matches(BaseContants.VerifyShopSettlement.REGEX_EMAIL,email)){
                throw new BusinessException("请输入正确的邮箱,请重新输入");
            }
            // 调用注册业务方法
            registerMethod(registerVo);
        }else {
            throw new BusinessException("参数异常！请重试");
        }
    }

    @Override
    public User loadByLogininfoId(Long logininfoId) {

        return userMapper.loadByLogininfoId(logininfoId);
    }


    @Transactional
    public void registerMethod(RegisterVo registerVo){
        String password = registerVo.getPassword();
        String confirmPassword = registerVo.getConfirmPassword();
        String phone = registerVo.getPhone();
        String smsCodeValue = registerVo.getSmsCodeValue();
        String email = registerVo.getEmail();
        String emailCodeValue = registerVo.getEmailCodeValue();
        // 调用非空校验工具类
        CheckCodeUtil.checkEmpty(phone,password,confirmPassword,smsCodeValue,emailCodeValue,email);
        // 调用短信验证码校验工具类
//        CheckCodeUtil.checkSmsCode(redisTemplate
//                ,BaseContants.VerifyCodeConstant.BUSINESS_REGISTER_PREFIX
//                ,username
//                ,code);
        // 判断密码是否一致
        if (!password.equals(confirmPassword)) {
            throw new BusinessException("两次密码不一致！请重新输入");
        }
        // 判断用户是否已注册，如果已注册提示用户
        User user = null;
        if (registerVo.getRegisterType().equals("phone")){
            CheckCodeUtil.checkSmsCode(redisTemplate,BaseContants.VerifyCodeConstant.BUSINESS_REGISTER_PREFIX,phone,smsCodeValue);
            user = userMapper.loadByPhone(phone);
        }else if (registerVo.getRegisterType().equals("email")){
            CheckCodeUtil.checkSmsCode(redisTemplate,BaseContants.VerifyCodeConstant.BUSINESS_REGISTER_PREFIX,email,emailCodeValue);
            user = userMapper.getByEmail(email);
        }
        if (user != null){
            throw new BusinessException("用户已注册，请直接登录，如果忘记密码，请点击忘记密码！");
        }
        // 调用封装好的方法，将注册后的数据存到数据库
        // 使用方法，将注册信息赋值给user
        user = register2User(registerVo);
        userMapper.add(user);
        // 再将得到的user传递给关联表loginfo
        Logininfo logininfo = user2Logininfo(user);
        // 在关联表中加入注册信息用户
        logininfoMapper.add(logininfo);
        // use中的loginfoid字段赋值
        user.setLogininfoId(logininfo.getId());
        // 调用修改方法，修改loginfo中的id值
        userMapper.update(user);

    }
    @Override
    public void update(User user) {
        userMapper.update(user);
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.update(logininfo);

    }
    //
    @Override
    public void remove(Long id) {
        Logininfo logininfo = logininfoMapper.loadById(id);
        logininfoMapper.remove(logininfo.getId());
        userMapper.remove(id);

    }

}
